package com.dataseek.iot.device.manager.controller;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.dataseek.iot.core.base.IController;
import com.dataseek.iot.core.constant.ResponseConst;
import com.dataseek.iot.core.request.QueryPage;
import com.dataseek.iot.core.request.QueryPage2;
import com.dataseek.iot.core.request.QueryParam;
import com.dataseek.iot.core.response.ResponseEntity;
import com.dataseek.iot.core.util.ParseUtil;
import com.dataseek.iot.core.util.WrapperUtil;
import com.dataseek.iot.device.manager.handler.DeviceHandler;
import com.dataseek.iot.mysql.entity.Device;
import com.dataseek.iot.mysql.service.impl.DeviceRecordServiceImpl;
import com.dataseek.iot.mysql.service.impl.DeviceServiceImpl;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author cc
 * @since 2021-09-19
 */
@RestController
@RequestMapping("/device")
@Api(tags = "设备接口")
public class DeviceController implements IController<Device> {

    @Autowired
    DeviceHandler deviceService;

    @Autowired
    DeviceServiceImpl deviceServiceImpl;



    @PutMapping("/addOne")
    @ApiOperation("保存单个设备")
    @Override
    public Mono<ResponseEntity> saveOne(@RequestBody Device entity) {
        Device user = entity;
        return deviceService.saveOne(user);
    }

    @PostMapping("/addBatch")
    @ApiOperation("批量保存设备数据")
    @Override
    public Mono<ResponseEntity> saveBatch(@RequestBody List<Device> lists) {
        return deviceService.saveBatch(lists);
    }


    @DeleteMapping("/{id}")
    @ApiOperation("根据ID移除设备信息")
    @Override
    public Mono<ResponseEntity> remove(@PathVariable String id) {
        return deviceService.remove(id);
    }

    @DeleteMapping("/removeByIds")
    @ApiOperation("根据ID批量移除设备信息")
    @Override
    public Mono<ResponseEntity> removeAll(@RequestBody List<String> ids) {
        return deviceService.removeAll(ids);
    }

    @DeleteMapping("/remove")
    @ApiOperation("根据条件移除设备信息")
    @Override
    public Mono<ResponseEntity> remove(@RequestBody List<QueryParam> params) {
        Wrapper wrapper = WrapperUtil.assembleParams(params);
        return deviceService.remove(wrapper);
    }

    @PostMapping("/updateOne")
    @ApiOperation("更新设备信息")
    @Override
    public Mono<ResponseEntity> updateOne(@RequestBody Device entity) {
        return deviceService.updateOne(entity);
    }

    @PostMapping("/update")
    @ApiOperation("根据条件更新设备信息")
    @Override
    public Mono<ResponseEntity> update(@RequestBody List<QueryParam> params) {
        Wrapper wrapper = WrapperUtil.assembleParams(params);
        return deviceService.update(wrapper);
    }

    @PostMapping("/updatePassword")
    @ApiOperation("更新密码")
    public Mono<ResponseEntity> updatePassword(@RequestBody Device user){
        return deviceService.updateOne(user);
    }

    @PostMapping("/updateBatch")
    @ApiOperation("批量更新")
    @Override
    public Mono<ResponseEntity> updateBatch(@RequestBody List<Device> entities) {
        return deviceService.updateBatch(entities);
    }

    @PostMapping("/page/find")
    @ApiOperation("无条件分页查询")
    @Override
    public Mono<ResponseEntity> page(@RequestBody Page p) {
        return deviceService.page(p);
    }

    @PostMapping("/page/findWithParam")
    @ApiOperation("分页查询，带查询条件")
    @Override
    public Mono<ResponseEntity> page(@RequestBody QueryPage queryPage) {
        if(queryPage==null||queryPage.getParams()==null||queryPage.getPage()==null){
            ResponseEntity entity  = new ResponseEntity();
            entity.setCode(ResponseConst.BAD_REQUEST_CODE);
            entity.setMsg(ResponseConst.BAD_REQUEST);
            return deviceService.defaultResponseOne(entity);
        }
        return deviceService.page(queryPage.getPage(), WrapperUtil.assembleParams(queryPage.getParams()));
    }

    /**
     * 根据IDS查询数据
     * @param ids
     * @return
     */
    @PostMapping("/findById")
    @ApiOperation("根据ID查询数据")
    @Override
    public Flux<ResponseEntity> findByIds(@RequestBody List<String> ids) {
        return deviceService.find(ids);
    }

    /**
     * 根据查询条件查询数据
     * @param params
     * @return
     */
    @PostMapping("/findByParams")
    @ApiOperation("根据查询条件查询参数")
    @Override
    public Flux<ResponseEntity> find(@RequestBody List<QueryParam> params){
        ResponseEntity entity = new ResponseEntity();
        if(params==null){
            entity.setCode(ResponseConst.BAD_REQUEST_CODE);
            entity.setMsg(ResponseConst.BAD_REQUEST);
            return deviceService.defaultResponseTwo(entity);
        }else if(params.size()==0){
            entity.setCode(ResponseConst.NULL_PARAM_CODE);
            entity.setMsg(ResponseConst.NULL_PARAM);
            return deviceService.defaultResponseTwo(entity);
        }
        return deviceService.find(WrapperUtil.assembleParams(params));
    }

    /**
     * 根据id条件查询数据
     * @param id
     * @return
     */
    @GetMapping("/{id}")
    @ApiOperation("根据ID查询设备")
    @Override
    public Mono<ResponseEntity> findOne(@PathVariable String id) {
        return deviceService.findOne(id);
    }

    /**
     * 查询所有数据
     * @return
     */
    @GetMapping("/findAll")
    @ApiOperation("查询所有")
    @Override
    public Flux<ResponseEntity> findAll() {
        return deviceService.findAll();
    }

    @PostMapping("/findByJSONParams")
    @ApiOperation("条件查询，没有分页")
    @Override
    public Flux<ResponseEntity> find(@RequestBody JSONObject json) {
        List<Device> devices = new ArrayList<>();
        ResponseEntity entity = new ResponseEntity();
        if(json.containsKey("line_code")){
            String[] codes = json.getString("line_code").split(",");
            for(String code : codes){
                json.put("line_code", code);
                QueryWrapper wrapper = ParseUtil.parseJson(json);
                List<Device> result = deviceServiceImpl.list(wrapper);
                devices.addAll(result);
            }
            entity.setData(ResponseConst.SUCCESS_CODE);
            entity.setMsg(ResponseConst.SUCCESS);
            entity.setData(devices);
            return Flux.just(entity);
        }else {
            QueryWrapper wrapper = ParseUtil.parseJson(json);
            return deviceService.find(wrapper);
        }

    }

    @PostMapping("/page/findByJSONParams")
    @ApiOperation("分页查询，传参为json")
    @Override
    public Mono<ResponseEntity> page(@RequestBody JSONObject json) {
        List<Device> devices = new ArrayList<>();
        ResponseEntity entity = new ResponseEntity();
        Page p= new Page();
        if(json.containsKey("line_code")){
            String[] codes = json.getString("line_code").split(",");
            for(String code : codes){
                json.put("line_code", code);
                QueryPage2 queryPage2 = ParseUtil.parseJsonWithPage(json);
                p = deviceServiceImpl.page(queryPage2.getPage(),queryPage2.getWrapper());
                devices.addAll(p.getRecords());
            }
            entity.setCode(ResponseConst.SUCCESS_CODE);
            entity.setMsg(ResponseConst.SUCCESS);
            p.setRecords(devices);
            entity.setData(p);
            return Mono.just(entity);
        }else {
            QueryPage2 queryPage2 = ParseUtil.parseJsonWithPage(json);
            return deviceService.page(queryPage2.getPage(), queryPage2.getWrapper());
        }
    }

    @GetMapping("/page/findByLineCode/{code}/{current}/{size}")
    @ApiOperation("根据线路编码查看设备分页")
    public Mono<ResponseEntity> page(@PathVariable String code, @PathVariable int current, @PathVariable int size){
        ResponseEntity entity = deviceService.getPageByLineCode(code, current, size);
        return Mono.just(entity);
    }

    @GetMapping("/findDeviceByLineId/{id}")
    @ApiOperation("根据路线ID获取设备")
    public Flux<ResponseEntity> getDevicesByLineId(@PathVariable String id){
        return Flux.just(deviceService.getLineInfoById(id));
    }


    @GetMapping("/findDeviceByLineCode/{code}")
    @ApiOperation("根据路线code获取设备")
    public Flux<ResponseEntity> getDevicesByLineCode(@PathVariable String code){
        return Flux.just(deviceService.getLineInfoByCode(code));
    }

    @GetMapping("/latestRecord/{deviceCode}")
    @ApiOperation("获取最新一条记录")
    public Mono<ResponseEntity> getLatestRecord(@PathVariable String deviceCode){
        return deviceService.getLatestRecord(deviceCode);
    }

}
